package com.kamistoat.meimeimall.common.sharding.strategy;

import com.kamistoat.meimeimall.common.sharding.Sharding;
import com.kamistoat.meimeimall.common.sharding.properties.DatabaseProperties;

/**
 * 按照key的数据范围进行切分。
 * 缺点是存在明显的写偏移，热点集中在新创建的表上。
 */
public class RangeShardingStrategy extends AbstractShardingStrategy {
    public static final Long TABLE_DATA_LIMIT = 50000000L;

    /**
     * 计算分表名的序号。和基础表名拼接称为最终的分表名
     *
     * @param shardingKeyValue   分库分表key在实际方法中的值
     * @param sharding           Sharding信息
     * @param databaseProperties 数据源属性
     * @return 计算分表
     */
    @Override
    public Integer calculateTableSuffix(String shardingKeyValue, Sharding sharding, DatabaseProperties databaseProperties) {
        long shardingKeyLong = Long.parseLong(shardingKeyValue);
        int shardingDatabaseCount = databaseProperties.getShardingDatabaseCount();
        int shardingPreTableCount = databaseProperties.getShardingPreTableCount();
        int slot = (int) (shardingKeyLong / TABLE_DATA_LIMIT);
        return slot % shardingPreTableCount;
    }

    /**
     * 计算分库名的序号。和基础库名拼接后，与目标分库建立链接
     *
     * @param shardingKeyValue   分库分表key在实际方法中的值
     * @param sharding           Sharding信息
     * @param databaseProperties 数据源属性
     * @return 计算分表
     */
    @Override
    public Integer calculateDatabaseSuffix(String shardingKeyValue, Sharding sharding, DatabaseProperties databaseProperties) {
        long shardingKeyLong = Long.parseLong(shardingKeyValue);
        int shardingDatabaseCount = databaseProperties.getShardingDatabaseCount();
        int shardingPreTableCount = databaseProperties.getShardingPreTableCount();
        int slot = (int) (shardingKeyLong / TABLE_DATA_LIMIT);
        return slot / shardingPreTableCount;
    }
}
